// rpc_pipes_client.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include "rpc_pipes_h.h" 
#include <windows.h>

int _tmain(int argc, _TCHAR* argv[])
{
	RPC_STATUS status;
	RPC_WSTR pszUuid             = NULL;
	RPC_WSTR pszProtocolSequence = (RPC_WSTR)L"ncacn_np";
	RPC_WSTR pszNetworkAddress   = NULL;
	RPC_WSTR pszEndpoint         = (RPC_WSTR)L"\\pipe\\hello";
	RPC_WSTR pszOptions          = NULL;
	RPC_WSTR pszStringBinding    = NULL;
	char* pszString      = "checking connection... 1 2 3...";
	unsigned long ulCode;

	status = RpcStringBindingCompose(pszUuid,
		pszProtocolSequence,
		pszNetworkAddress,
		pszEndpoint,
		pszOptions,
		&pszStringBinding);

	if (status) exit(status);

	status = RpcBindingFromStringBinding(pszStringBinding, &RPC_Pipes_Interface_v1_0_c_ifspec);

	if (status) exit(status);

	RpcTryExcept  
	{
		PrintMsg(pszString);
		Shutdown();
	}
	RpcExcept(1) 
	{
		ulCode = RpcExceptionCode(); // RPC_S_CANNOT_SUPPORT
		printf("Runtime reported exception 0x%lx = %ld\n", ulCode, ulCode);
	}
	RpcEndExcept

	status = RpcStringFree(&pszStringBinding); 

	if (status) exit(status);

	status = RpcBindingFree(&RPC_Pipes_Interface_v1_0_c_ifspec);

	if (status) exit(status);

	exit(0);
}

void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
{
	return(malloc(len));
}

void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
{
	free(ptr);
}

// Pipes code
/*
#define BUF_SIZE 1024
#define PIPE_SIZE 1
#define IN_VALUE 7
typedef char* rpc_ss_pipe_state_t;
typedef unsigned long ulong;

long *globalPipeData;
long    globalBuffer[BUF_SIZE];
 
ULONG   pipeDataIndex; // state variable

// In-Pipe

void SendLongs()
{
    LONG_PIPE inPipe;
    int i;
    globalPipeData =
        (long *)malloc( sizeof(long) * PIPE_SIZE );
 
    for (i=0; i<PIPE_SIZE; i++)
        globalPipeData[i] = IN_VALUE;
 
    pipeDataIndex = 0;
    inPipe.state =  (rpc_ss_pipe_state_t )&pipeDataIndex;
    inPipe.pull  = PipePull;
    inPipe.alloc = PipeAlloc;
 
    InPipe( inPipe ); // Make the rpc
 
    free( (void *)globalPipeData );

}//end SendLongs
 
void __stdcall PipeAlloc( rpc_ss_pipe_state_t stateInfo,
                ulong requestedSize,
                long **allocatedBuffer,
                ulong *allocatedSize )
{ 
    ulong *state = (ulong *)stateInfo;
    if ( requestedSize > (BUF_SIZE*sizeof(long)) )
    {
       *allocatedSize = BUF_SIZE * sizeof(long);
    }
    else
    {
       *allocatedSize = requestedSize;
    }
    *allocatedBuffer = globalBuffer; 
} //end PipeAlloc
 
void __stdcall PipePull( rpc_ss_pipe_state_t stateInfo,
               long *inputBuffer,
               ulong maxBufSize,
               ulong *sizeToSend )
{
    ulong currentIndex;
    ulong i;
    ulong elementsToRead;
    ulong *state = (ulong *)stateInfo;

    currentIndex = *state;
    if (*state >=  PIPE_SIZE )
    {
        *sizeToSend = 0; // end of pipe data
        *state = 0; // Reset the state = global index
    }
    else 
    {
        if ( currentIndex + maxBufSize > PIPE_SIZE )
            elementsToRead = PIPE_SIZE - currentIndex;
        else
            elementsToRead = maxBufSize;
 
        for (i=0; i < elementsToRead; i++)
        {
            //client sends data 
            inputBuffer[i] = globalPipeData[i + currentIndex];
        }
 
        *state +=   elementsToRead;
        *sizeToSend = elementsToRead;
    } 
}//end PipePull

// Out-Pipe

void ReceiveLongs()
{
    LONG_PIPE *outputPipe;
    idl_long_int i;
 
    globalPipeData =
        (long *)malloc( sizeof(long) * PIPE_SIZE );
    
    pipeDataIndex = 0;
    outputPipe.state =  (rpc_ss_pipe_state_t )&pipeDataIndex;
    outputPipe.push  = PipePush;
    outputPipe.alloc = PipeAlloc;
 
    OutPipe( &outputPipe ); // Make the rpc
 
    free( (void *)globalPipeData );
 
}//end ReceiveLongs()

void PipeAlloc( rpc_ss_pipe_state_t stateInfo,
                ulong requestedSize,
                long **allocatedBuffer,
                ulong *allocatedSize )
{ 
    ulong *state = (ulong *)stateInfo;
    if ( requestedSize > (BUF_SIZE*sizeof(long)) )
    {
       *allocatedSize = BUF_SIZE * sizeof(long);
    }
    else
    {
       *allocatedSize = requestedSize;
    }
    *allocatedBuffer = globalBuffer; 
} //end PipeAlloc
 
void PipePush( rpc_ss_pipe_state_t stateInfo,
               long *buffer,
               ulong numberOfElements )
{
    ulong elementsToCopy, i;
    ulong *state = (ulong *)stateInfo;

    if (numberOfElements == 0) // end of data
    {
        *state = 0; // Reset the state = global index
    }
    else
    {
        if (*state + numberOfElements > PIPE_SIZE)
            elementsToCopy = PIPE_SIZE - *state;
        else
            elementsToCopy = numberOfElements;
 
        for (i=0; i <elementsToCopy; i++)
        { 
            // client receives data
            globalPipeData[*state] = buffer[i];
            (*state)++;
        }
    }
}//end PipePush
*/